package visiteurs;

import gestionSites.Page;

import org.htmlparser.tags.Tag;

import aspiration.Link;
import aspiration.LinkList;
import aspiration.SiteCapturer;

import statistiques.StatistiquePages;

/**
 * visiteur extrayant les liens apparaissant sur une page
 * 
 */
public class URLExtractingVisitor extends Visitor {

	/**
	 * profondeur actuelle
	 */
	private int depth;
	
	/**
	 * liste des pages � capturer
	 */
	private LinkList pagesToBeCaptured;
	
	/**
	 * liste des pages captur�es
	 */
	private LinkList captured;
	
	/**
	 * liste des fichiers � capturer
	 */
	private LinkList filesToBeCaptured;
	
	/**
	 * liste des css � capturer
	 */
	private LinkList cssToBeCaptured;
	
	/**
	 * profondeur maximale
	 */
	private int maxDepth;
	
	/**
	 * emplacement courant dans le site (exemple : dossier1/images/
	 */
	private String currentReps;
	
	/**
	 * statistiques sur les pages
	 */
	private StatistiquePages statsPages;

	/**
	 * constructeur
	 * 
	 * @param _depth profondeur
	 * @param _sc aspirateur de site
	 * @param _current url couramment visit�e
	 * @param sp stats sur les pages
	 */
	public URLExtractingVisitor(int _depth, SiteCapturer _sc, String _current, StatistiquePages sp) {
		
		super(_sc.getSource());
		
		depth = _depth;
		maxDepth = _sc.getMaxDepth();
		pagesToBeCaptured = _sc.getPagesToBeCaptured();
		captured = _sc.getPagesCaptured();
		filesToBeCaptured = _sc.getFilesToBeCaptured();
		cssToBeCaptured = _sc.getCssToBeCaptured();
		statsPages = sp;
		
		String fin = _current.substring(_current.lastIndexOf("/"), _current.length());
		if (fin.contains(".")){
			currentReps = _current.substring(0, _current.lastIndexOf("/"));
		}else{
			currentReps = new String(_current);
		}

	}
	
	/**
	 * visite d'une balise afin d'en extraire les liens
	 * @param tag balise visit�e
	 */
	public void visitTag(Tag tag){
		
		String tagName = tag.getTagName();
		tagName = tagName.toUpperCase();
		int codeName = getCodeName(tagName);
		Link link;
		String tmp;
		switch(codeName) {
			case IMG:
			case SCRIPT:	
			case FRAME:
				
				tmp = toAbsolute(tag.getAttribute("SRC"));
				
			
				if(tmp != null){
					tmp = tmp.replaceAll("/\\?[^/]*/", "/");
					
					if(! tmp.isEmpty()){
						link = new Link(tmp,0);
						filesToBeCaptured.add(link);		
					}
				}
				break;
			case LINK:
				tmp = toAbsolute(tag.getAttribute("HREF"));
				if (tmp != null){
					tmp = tmp.replaceAll("/\\?[^/]*/", "/");
					if(! tmp.isEmpty()){
						link = new Link(tmp,0);
						filesToBeCaptured.add(link);
						if (tmp.endsWith(".css"))
							cssToBeCaptured.add(link);
					}
				}
				break;
			case A:
				tmp = toAbsolute(tag.getAttribute("HREF"));
				if(tmp != null)
					tmp = tmp.replaceAll("/\\?[^/]*/", "/");
				
				if(tmp != null && !tmp.contains("@")){
					if (!tmp.isEmpty()){
						link = new Link(tmp, depth);
					
						Page page = statsPages.getPage(link.getUrl());
						if (page != null)
							page.incrementerNbRef();
						
						if (!captured.contains(link) && depth<maxDepth){
							if(tmp.endsWith(".pdf") || tmp.endsWith(".png") || tmp.endsWith(".jpg")
							   || tmp.endsWith(".gif") || tmp.endsWith(".jpeg") || tmp.endsWith(".doc")
							   || tmp.endsWith(".docx") || tmp.endsWith(".xls") || tmp.endsWith(".odt")
							   || tmp.endsWith(".avi") || tmp.endsWith(".bmp") || tmp.endsWith(".rtf")
							   || tmp.endsWith(".zip") || tmp.endsWith(".rar") || tmp.endsWith(".mp3")
							   || tmp.endsWith(".mp4") || tmp.endsWith(".mpeg") || tmp.endsWith(".ods")
							   || tmp.endsWith(".pps") || tmp.endsWith(".ppt") || tmp.endsWith(".pptx")
							   || tmp.endsWith(".jpg") || tmp.endsWith(".txt") || tmp.endsWith(".wav")
							   || tmp.endsWith(".wma") || tmp.endsWith(".wmv") || tmp.endsWith(".xlsx")
							   || tmp.endsWith(".xml"))
								filesToBeCaptured.add(link);
							else
								pagesToBeCaptured.add(link);
						}
					}
				}
				break;
		}
	}
	
	/**
	 * transformation d'un lien en absolu
	 * @param url url � transformer
	 * @return lien absolu
	 */
	private String toAbsolute(String url){

		
		if(url == null)
			return url;
		
		if (url.isEmpty()){
			return url;
		}
		
		if (url.contains("#"))
			url = url.substring(0, url.indexOf("#"));
		
		if(url.startsWith("?")){
			return currentReps + "/" + url;
		}

		if (url.toUpperCase().contains("JAVASCRIPT"))
			return null;
			
		//si c'est un lien absolu qui appartient au site
		if (url.startsWith(source))
			return url;
			
		//si c'est un lien relatif du site	
		if (!url.toLowerCase().startsWith("http")) {
				
			String tmp = new String(currentReps);
				
			while (url.contains("..")){
				//System.out.print("url: "+url);
				if (url.lastIndexOf("..")!=0){
					
					url = url.substring(0,url.lastIndexOf(".."))
					+ url.substring(url.lastIndexOf("..")+3, url.length());
					tmp = removeLastRepertory(tmp);
				}else{
					
					url = url.substring(url.indexOf("/")+1, url.length());
					tmp = removeLastRepertory(tmp);
				}
				//System.out.println("   url: "+url);
			}
				
			if (!tmp.endsWith("/")){
				url = (url.startsWith("/")) ? tmp + url :  tmp + "/" + url;
			}else{
				url = tmp + url;
			}
				
		}else{
				
			return null;
		}

		return url;
	}
	

	/**
	 * transformation d'un lien en absolu
	 * @param url url � transformer
	 * @return lien absolu
	 */
	public static String addressToAbsolute(String url, String currentReps, String source){

		
		if(url == null)
			return url;
		
		if (url.isEmpty()){
			return url;
		}
		
		if (url.contains("#"))
			url = url.substring(0, url.indexOf("#"));
		
		if(url.startsWith("?")){
			return currentReps + "/" + url;
		}

		if (url.toUpperCase().contains("JAVASCRIPT"))
			return null;
			
		//si c'est un lien absolu qui appartient au site
		if (url.startsWith(source))
			return url;
			
		//si c'est un lien relatif du site	
		if (!url.toLowerCase().startsWith("http")) {
				
			String tmp = new String(currentReps);
				
			while (url.contains("..")){
				//System.out.print("url: "+url);
				if (url.lastIndexOf("..")!=0){
					
					url = url.substring(0,url.lastIndexOf(".."))
					+ url.substring(url.lastIndexOf("..")+3, url.length());
					tmp = removeLastRepertory(tmp);
				}else{
					
					url = url.substring(url.indexOf("/")+1, url.length());
					tmp = removeLastRepertory(tmp);
				}
				//System.out.println("   url: "+url);
			}
				
			if (!tmp.endsWith("/")){
				url = (url.startsWith("/")) ? tmp + url :  tmp + "/" + url;
			}else{
				url = tmp + url;
			}
				
		}else{
				
			return null;
		}

		return url;
	}
	
	/**
	 * suppression du dernier r�pertoire du chemin courant
	 * @param s chemin courant
	 * @return chemin tronqu�
	 */	
	private static String removeLastRepertory(String s){
		s = s.substring(0, s.lastIndexOf("/"));
		return s;
	}
	

	
}
